class_name Tag
extends RefCounted

## 标签名称
var name: String

## 子标签
var _children: Dictionary


func _init(init_name: String) -> void:
	name = init_name
	_children = {}


func get_tag(path: String) -> Tag:
	if path.is_empty():
		return self
	
	var segments := path.split(".", false, 1)
	var current_segment = segments[0]
	var remaining_path = segments[1] if segments.size() > 1 else ""
	
	if not _children.has(current_segment):
		return null
	
	return _children[current_segment].get_tag(remaining_path)


func add_tag(tag_path: String) -> Tag:
	var segments := tag_path.split(".")
	if segments.is_empty():
		return self
	
	var current_tag: Tag = self
	for segment in segments:
		if not current_tag._children.has(segment):
			var new_tag = Tag.new(segment)
			current_tag._children[segment] = new_tag
		current_tag = current_tag._children[segment]
	return current_tag


func add_tags(tag_paths: Array[String]) -> void:
	for tag_path: String in tag_paths:
		add_tag(tag_path)


func remove_tag(tag_path: String) -> bool:
	# INFO: 级联清理空容器
	var segments := tag_path.split(".")
	if segments.is_empty():
		return false

	var parent_stack := []  # 记录父级容器栈
	var current_tag: Tag = self
	
	# 1. 导航到目标标签
	for segment in segments:
		if not current_tag._children.has(segment):
			return false  # 路径不存在
		
		parent_stack.append(current_tag)
		current_tag = current_tag._children[segment]
	
	# 2. 从直接父级删除
	var direct_parent = parent_stack[-1]
	if not direct_parent._children.erase(current_tag.name):
		return false
	
	# 3. 反向清理空容器（从下往上）
	for i in range(parent_stack.size()-1, 0, -1):
		var current_parent = parent_stack[i]
		var grand_parent = parent_stack[i-1]
		
		if current_parent._children.is_empty():
			grand_parent._children.erase(current_parent.name)
		else:
			break  # 遇到非空容器则停止清理
	
	return true


func remove_tags(tag_paths: Array[String]) -> void:
	for tag_path: String in tag_paths:
		remove_tag(tag_path)


func has_tag(path: String) -> bool:
	return get_tag(path) != null


func has_any_tag(paths: Array[String]) -> bool:
	for path: String in paths:
		if has_tag(path):
			return true
	return false


func has_all_tags(paths: Array[String]) -> bool:
	for path: String in paths:
		if not has_tag(path):
			return false
	return true


func get_child_tags() -> Array:
	return _children.values()


func get_child_tag_names() -> Array:
	return _children.keys()


func get_leaf_tag_paths(parent_path: String = "") -> Array[String]:
	var full_path = parent_path + "." + name if not parent_path.is_empty() else name
	var result: Array[String] = []
	
	if _children.is_empty():
		result.append(full_path)
	else:
		for child in _children.values():
			result.append_array(child.get_leaf_tag_paths(full_path))
	
	return result
